package com.rent.message.controller;

import com.rent.common.constant.CommonConstant;
import com.rent.message.constant.MessageConstant;
import com.rent.message.pojo.dto.SendMessageDto;
import com.rent.message.ws.MessagePushService;
import com.rent.message.ws.MessageSessionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

@Controller
@Slf4j
public class MessageController {
    
    @Autowired
    private MessageSessionService sessionService;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private MessagePushService messagePushService;
    
    /**
     * 用户连接后注册到消息系统
     * 前端：stompClient.send("/app/message/register", {}, userInfo)
     */
    @MessageMapping("/message/register")
    public void registerUser(@Payload Map<String, Object> userInfo, SimpMessageHeaderAccessor headerAccessor) {


        // 从session属性中获取已认证的用户ID
        Map<String, Object> sessionAttributes = headerAccessor.getSessionAttributes();
        String userId = sessionAttributes != null ? (String) sessionAttributes.get("userId") : null;
        String username = sessionAttributes != null ? (String) sessionAttributes.get("username") : null;

        if (userId == null) {
            log.warn("用户注册失败: 未找到认证信息");
            sendError(headerAccessor.getSessionId(), "用户未认证");
            return;
        }

        String sessionId = headerAccessor.getSessionId();
        String uuid = (String) userInfo.get("uuid");

        log.info("用户注册到消息系统: username={}, userId={}, sessionId={}",username, userId, sessionId);

        //设置默认的聊天对象为0
        redisTemplate.opsForValue().set(MessageConstant.CHAT_USER_ID + userId, 0L);

        // 存储映射：用户ID -> SessionId
        sessionService.saveUserSession(userId, sessionId, uuid);

        // 立即发送欢迎消息测试连接
        messagePushService.sendWelcomeMessage(userId, uuid);
//        sendWelcomeMessage(userId, userId);

    }


    /*
     * 发送消息
     * 前端：stompClient.send("/app/chat/send", {}, messageData)
     */
    @MessageMapping("/chat/send")
    public void sendMessage(@Payload Map<String, Object> messageData, SimpMessageHeaderAccessor headerAccessor) {
        try {
            log.info("收到发送消息请求: {}", messageData);

            // 从消息中提取数据
            String content = (String) messageData.get("content");
            Object toUserIdObj = messageData.get("toUserId");
            String toUserId = null;

            // 处理toUserId，可能是String或Integer
            if (toUserIdObj != null) {
                if (toUserIdObj instanceof Integer) {
                    toUserId = String.valueOf(toUserIdObj);
                } else {
                    toUserId = toUserIdObj.toString();
                }
            }

            String picture = (String) messageData.get("picture");

            // 从Session中获取发送者信息
            String sessionId = headerAccessor.getSessionId();
            String fromUserId = getUserIdFromSession(sessionId);

            if (fromUserId == null) {
                log.error("发送消息失败: 用户未登录, sessionId: {}", sessionId);
                sendError(sessionId, "用户未登录");
                return;
            }

            if (toUserId == null) {
                log.error("发送消息失败: 接收者ID为空");
                sendError(sessionId, "接收者ID不能为空");
                return;
            }

            // 构建消息对象
            Map<String, Object> message = new HashMap<>();
            message.put("id", generateMessageId());
            message.put("type", MessageConstant.MESSAGE_TYPE_CHAT);
            message.put("fromUserId", fromUserId);
            message.put("toUserId", toUserId);
            message.put("content", content);
            message.put("picture", picture);
            message.put("timestamp", System.currentTimeMillis());

            log.info("用户 {} 发送消息给 {}: {}", fromUserId, toUserId, content);
            // 发送给接收者
            messagePushService.sendToUser(toUserId, message);

            // 也发送给发送者自己（确认消息已发送）
//            messagePushService.sendToUser(fromUserId, message);

        } catch (Exception e) {
            log.error("发送消息失败", e);
            String sessionId = headerAccessor.getSessionId();
            sendError(sessionId, "发送消息失败: " + e.getMessage());
        }
    }


    /**
     * 从Session获取用户ID
     */
    private String getUserIdFromSession(String sessionId) {
        String sessionKey = CommonConstant.USER_SESSION + sessionId;
        Object value = redisTemplate.opsForValue().get(sessionKey);
        if (value == null) {
            return null;
        }
        return value.toString();
    }

    /**
     * 发送给接收者
     */
    private void sendToReceiver(String toUserId, Map<String, Object> message) {
        Set<Object> receiverSessions = sessionService.getUserSessions(toUserId);
        if (receiverSessions != null && !receiverSessions.isEmpty()) {
            for (Object sessionId : receiverSessions) {
                messagingTemplate.convertAndSendToUser(
                        sessionId.toString(),
                        "/queue/messages",
                        message
                );
            }
            log.info("消息已推送给接收者: {}, 会话数: {}", toUserId, receiverSessions.size());
        } else {
            log.info("接收者 {} 不在线，消息已保存", toUserId);
        }
    }

    /**
     * 发送给发送者（确认消息）
     */
    private void sendToSender(String fromUserId, Map<String, Object> message) {
        Set<Object> senderSessions = sessionService.getUserSessions(fromUserId);
        if (senderSessions != null) {
            for (Object sessionId : senderSessions) {
                messagingTemplate.convertAndSendToUser(
                        sessionId.toString(),
                        "/queue/messages",
                        message
                );
            }
        }
    }

    /**
     * 发送错误信息
     */
    private void sendError(String sessionId, String errorMessage) {
        Map<String, Object> error = new HashMap<>();
        error.put("type", "ERROR");
        error.put("content", errorMessage);
        error.put("timestamp", System.currentTimeMillis());

        messagingTemplate.convertAndSendToUser(sessionId, "/queue/errors", error);
    }

    /**
     * 生成消息ID
     */
    private String generateMessageId() {
        return  System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(1000) + "";
    }
}